//
//  Stack.h
//  Stack
//
//  Created by Роман Ануфриев on 05.03.14.
//  Copyright (c) 2014 Роман Ануфриев. All rights reserved.
//

#ifndef _STACK_H
#define _STACK_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

// #define ASSERT_OK() if (!Stack_t::OK ())					\
							{									\
							Stack_t::Dump ()					\
							assert (!"Smth is bad with stack");	\
							}

#define ASSERT_OK(type) if (!type::OK())					\
							{									\
							type::Dump(),					\
                            assert (!"not_OK -> it is bad");	\
							}


const int STK_SZ = 5;
const int POISON = -666;

typedef double elem_t;

struct Stack_t
	{
	// private -> class, !struct
	int count_;
	elem_t data_[STK_SZ];
	
	Stack_t ();
	~Stack_t ();
	
	bool OK () const;
	void Dump () const;
	
	bool Push (elem_t value);
	
	int& show_count (Stack_t st);
	
	};

Stack_t::Stack_t ():
	count_ (0)
	{
	memset (data_, 0, sizeof (data_));
	}

Stack_t::~Stack_t ()
	{
	Stack_t::OK ();
	
	count_ = POISON;
	memset (data_, POISON, sizeof (data_));
	
	Stack_t::OK ();
	
	Stack_t::Dump ();
	}

bool Stack_t::OK () const
	{
	return (this && (count_ >= 0) && (count_ <= STK_SZ));
	}

void Stack_t::Dump () const
	{
	printf ("Dump of the stack:\n");
        if (Stack_t::OK () == 1)
                printf ("  the stack is OK;\n" );
        else
                printf ("  the stack is BAD;\n");
        // printf ("  the address of the beginning of the stack: %x;\n", st);
        
        printf ("\t{\n"                                      );
        printf ("\tcount_ = %d\n",            Stack_t::count_);
        printf ("\tSTK_SZ = %d\n\n",                   STK_SZ);

        for (int i = 0; i < STK_SZ; i++)
                {
                printf ("\tdata_[%d] = %f ;", i, Stack_t::data_[i] );
                
                if (i < (Stack_t::count_) )
                        printf (              " *\n"               );
                else
                        printf (              " ;\n"               );
                }
                        
        printf("\t}\n"                                       );
	}

bool Stack_t::Push (elem_t value)
	{
	ASSERT_OK (Stack_t);
		
	data_[count_] = value;
	count_++;
	
	ASSERT_OK (Stack_t);
	
	return true;
	}

int& Stack_t::show_count (Stack_t st)
	{
	return st.count_;
	}



#endif /* _STACK_H */